package services

import (
    "fmt"
    "sync"
    "time"
    "volux/utils"
)

type MetricsService struct {
    mu             sync.RWMutex
    metrics        map[string]*SubsystemMetrics
    spdkClient     *utils.SPDKClient
    collectInterval time.Duration
}

type SubsystemMetrics struct {
    NQN           string    `json:"nqn"`
    ReadIOPS      int64     `json:"read_iops"`
    WriteIOPS     int64     `json:"write_iops"`
    ReadLatency   float64   `json:"read_latency_us"`
    WriteLatency  float64   `json:"write_latency_us"`
    QueueDepth    int       `json:"queue_depth"`
    ReadBW        int64     `json:"read_bandwidth_mbps"`
    WriteBW       int64     `json:"write_bandwidth_mbps"`
    ErrorCount    int64     `json:"error_count"`
    Timestamp     time.Time `json:"timestamp"`
}

type AlertConfig struct {
    LatencyThreshold  float64 `json:"latency_threshold_us"`
    ErrorRateThreshold float64 `json:"error_rate_threshold"`
    QueueDepthThreshold int   `json:"queue_depth_threshold"`
}

func NewMetricsService(client *utils.SPDKClient) *MetricsService {
    ms := &MetricsService{
        metrics:         make(map[string]*SubsystemMetrics),
        spdkClient:      client,
        collectInterval: time.Second * 5,
    }
    go ms.collector()
    return ms
}

func (ms *MetricsService) collector() {
    ticker := time.NewTicker(ms.collectInterval)
    for range ticker.C {
        ms.collectMetrics()
    }
}

func (ms *MetricsService) collectMetrics() {
    ms.mu.Lock()
    defer ms.mu.Unlock()

    subsystems, err := ms.spdkClient.GetSubsystems()
    if err != nil {
        return
    }

    for _, sub := range subsystems.([]interface{}) {
        subsystem := sub.(map[string]interface{})
        nqn := subsystem["nqn"].(string)
        
        // 调用 GetSubsystemStats 时去除 nqn 参数
        stats, err := ms.spdkClient.GetSubsystemStats()
        if err != nil {
            continue
        }

        ms.updateMetrics(nqn, stats)
    }
}

func (ms *MetricsService) updateMetrics(nqn string, resp interface{}) {
    if resp == nil {
        utils.LogError("metrics_service: received nil result")
        return
    }
    if _, ok := resp.([]interface{}); ok {
        utils.LogError("metrics_service: received result as []interface{}, skipping metrics update")
        return
    }
    data, ok := resp.(map[string]interface{})
    if !ok {
        utils.LogError("metrics_service: result is not map[string]interface{}")
        return
    }
    statsMap := data
    metrics := &SubsystemMetrics{
        NQN:          nqn,
        ReadIOPS:     int64(statsMap["read_iops"].(float64)),
        WriteIOPS:    int64(statsMap["write_iops"].(float64)),
        ReadLatency:  statsMap["read_latency_us"].(float64),
        WriteLatency: statsMap["write_latency_us"].(float64),
        QueueDepth:   int(statsMap["queue_depth"].(float64)),
        ReadBW:       int64(statsMap["read_bandwidth"].(float64)) / (1024 * 1024),
        WriteBW:      int64(statsMap["write_bandwidth"].(float64)) / (1024 * 1024),
        ErrorCount:   int64(statsMap["error_count"].(float64)),
        Timestamp:    time.Now(),
    }
    ms.metrics[nqn] = metrics
    
    // 检查告警条件
    ms.checkAlerts(metrics)
}

func (ms *MetricsService) checkAlerts(metrics *SubsystemMetrics) {
    // 检查延迟告警
    if metrics.ReadLatency > 1000 || metrics.WriteLatency > 1000 {
        ms.triggerAlert("HIGH_LATENCY", metrics)
    }

    // 检查错误率
    if metrics.ErrorCount > 100 {
        ms.triggerAlert("HIGH_ERROR_RATE", metrics)
    }

    // 检查队列深度
    if metrics.QueueDepth > 1000 {
        ms.triggerAlert("HIGH_QUEUE_DEPTH", metrics)
    }
}

func (ms *MetricsService) triggerAlert(alertType string, metrics *SubsystemMetrics) {
    // TODO: 实现告警通知逻辑 (可以集成第三方告警系统)
}

func (ms *MetricsService) GetMetrics(nqn string) (*SubsystemMetrics, error) {
    ms.mu.RLock()
    defer ms.mu.RUnlock()
    
    metrics, exists := ms.metrics[nqn]
    if (!exists) {
        return nil, fmt.Errorf("no metrics found for subsystem: %s", nqn)
    }
    return metrics, nil
}
